package com.atguigu.ssyx.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.ssyx.client.activity.ActivityFeignClient;
import com.atguigu.ssyx.client.product.ProductFeignClient;
import com.atguigu.ssyx.common.security.AuthContextHolder;
import com.atguigu.ssyx.enums.SkuType;
import com.atguigu.ssyx.model.product.Category;
import com.atguigu.ssyx.model.product.SkuInfo;
import com.atguigu.ssyx.model.search.SkuEs;
import com.atguigu.ssyx.search.repository.SkuRepository;
import com.atguigu.ssyx.search.service.SkuService;
import com.atguigu.ssyx.vo.search.SkuEsQueryVo;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class SkuServiceImpl implements SkuService {

    private final SkuRepository skuRepository;
    private final ProductFeignClient productFeignClient;
    private final ActivityFeignClient activityFeignClient;

    private final RedisTemplate redisTemplate;

    @Override
    public void upperSku(Long skuId) {
        //创建数据封装SkuEs对象
        SkuEs skuEs = new SkuEs();
        //1.通过远程调用根据skuId获取商品信息
        SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
        if (skuInfo == null) {
            return;
        }
        //2.根据商品信息获取分类信息
        Category category = productFeignClient.getCategory(skuInfo.getCategoryId());
        //3.获取到数据封装到SkuES对象当中
        if (category != null) {
            skuEs.setCategoryId(category.getId());
            skuEs.setCategoryName(category.getName());

        }
        skuEs.setId(skuInfo.getId());
        skuEs.setKeyword(skuInfo.getSkuName() + "," + category.getName());
        skuEs.setWareId(skuInfo.getWareId());
        skuEs.setIsNewPerson(skuInfo.getIsNewPerson());
        skuEs.setImgUrl(skuInfo.getImgUrl());
        skuEs.setTitle(skuInfo.getSkuName());
        if (skuInfo.getSkuType() == SkuType.COMMON.getCode()) {
            skuEs.setSkuType(0);
            skuEs.setPrice(skuInfo.getPrice().doubleValue());
            skuEs.setStock(skuInfo.getStock());
            skuEs.setSale(skuInfo.getSale());
            skuEs.setPerLimit(skuInfo.getPerLimit());
        } else {
            //TODO 待完善-秒杀商品

        }
        //保存数据到es里
        SkuEs save = skuRepository.save(skuEs);
        log.error("上架商品信息:{}", JSON.toJSONString(save));


    }

    @Override
    public void lowerSku(Long skuId) {
        skuRepository.deleteById(skuId);

    }

    @Override
    public void deleteSku(Long skuId) {

        //删除es中的商品信息
        skuRepository.deleteById(skuId);
        log.error("删除商品成功~~~~~~~~~~~~~~~~~~~~~~~");


    }

    @Override
    public List<SkuEs> findHotSkuList() {
        PageRequest pageable = PageRequest.of(0, 10);

        //根据热度分数降序排序，取出前10条数据
        Page<SkuEs> p = skuRepository.findByOrderByHotScoreDesc(pageable);
        //获取到数据集合
        List<SkuEs> skuEsList = p.getContent();
        return skuEsList;
    }

    @Override
    public Page<SkuEs> search(PageRequest pageRequest, SkuEsQueryVo skuEsQueryVo) {
        //1.设置当前登录用户的仓库id
        skuEsQueryVo.setWareId(AuthContextHolder.getWareId());
        //2.调用SkuRepository方法，根据springData命名规范进行查询SkuEs里的数据
        Page<SkuEs> page = null;
        String keyword = skuEsQueryVo.getKeyword();
        if (keyword.isEmpty()) {
            page = skuRepository.findByCategoryIdAndWareId(skuEsQueryVo.getCategoryId(), skuEsQueryVo.getWareId(), pageRequest);
        } else {
            page = skuRepository.findByKeywordAndWareId(skuEsQueryVo.getKeyword(), skuEsQueryVo.getWareId(), pageRequest);
        }

        //3.查询商品参加优惠活动
        List<SkuEs> skuEsList = page.getContent();
        //遍历skuEsList,得到所有的SkuId对象
        if (CollectionUtils.isNotEmpty(skuEsList)) {
            List<Long> skuIdList = skuEsList.stream().map(skuEs -> skuEs.getId()).collect(Collectors.toList());
            //根据SkuId列表远程调用，调用service-activity接口，查询优惠活动信息
            //key是SkuId,value是优惠活动规则列表
            //一个商品参加一个活动，一个活动多个规则
//            HashMap<Long, List<String>> map = new HashMap<>();//TODO 远程调用

            Map<Long, List<String>> map = activityFeignClient.findActivity(skuIdList);
            //封装数据到SkuEs对象里的ruleList字段中
            if (map != null) {
                //遍历skuEsList集合，根据SkuId获取对应的优惠活动规则列表
                skuEsList.forEach(skuEs -> {
                    //通过key获取对应的优惠活动规则列表
                    skuEs.setRuleList(map.get(skuEs.getId()));
                });
            }
        }
        return page;
    }

    @Override

    @Async//异步执行
    public void updateHotSku(Long skuId) {
        //1.定义key
        String key = "sku:hotScore:";
        // 2. 在 Redis 的有序集合（ZSet）中，给 "skuId:123" 成员的分数 +1
        Double hotScore = redisTemplate.opsForZSet().incrementScore(key, skuId.toString(), 1);


        // 3. 如果当前热度分是 10 的倍数（如 10, 20, 30...）
        if (hotScore % 10 == 0) {
            // 4. 从 Elasticsearch 中查询该 SKU 的文档
            Optional<SkuEs> optional = skuRepository.findById(skuId);
            //5.获取SkuEs对象
            SkuEs skuEs = optional.get();
            //6.更新热度分数（取整）
            skuEs.setHotScore(Math.round(hotScore));
            //7.保存到es里
            skuRepository.save(skuEs);

        }
    }
}
